package com.romeo_foxtrot.labs.solr.client.json;

import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.core.client.JsArray;
import com.google.gwt.core.client.JsArrayString;

public class SearchResult extends JavaScriptObject {

	protected SearchResult() {
	}

	public final native FacetCounts getFacetCounts() /*-{
		return this["facet_counts"];
	}-*/;

	public final native ResponseHeader getResponseHeader() /*-{
		return this["responseHeader"];
	}-*/;

	public final native Response getResponse() /*-{
		return this["response"];
	}-*/;

	public static class FacetCounts extends JavaScriptObject {

		protected FacetCounts() {
		}

		public final native JsArray<FacetDate> getFacetDates() /*-{
			var pairs = [];
			var i = -1;

			var obj = this["facet_dates"];
			for (var prop in obj) {
				i++;
				pairs[i] = {
					"name": prop,
					"value": obj[prop]
				};
			}

			return pairs;
		}-*/;

		public final native JsArray<FacetField> getFacetFields() /*-{
			var pairs = [];
			var i = -1;

			var obj = this["facet_fields"];
			for (var prop in obj) {
				i++;
				pairs[i] = {
					"name": prop,
					"value": obj[prop]
				};
			}

			return pairs;
		}-*/;

		public final native JavaScriptObject getFacetQueries() /*-{
			return this["facet_queries"];
		}-*/;

		public static class FacetField extends JavaScriptObject {

			protected FacetField() {
			}

			public final native String getName() /*-{
				return this["name"];
			}-*/;

			public final native JsArray<Hits> getTerms() /*-{
				var hits = [];
				var i = -1;

				var mixture = this["value"];
				var mixtureIndex = 0;
				while (mixtureIndex < mixture.length) {
					i++;
					hits[i] = {
						"name": mixture[mixtureIndex],
						"value": mixture[mixtureIndex + 1]
					};

					mixtureIndex += 2;
				}

				return hits;
			}-*/;

		}

		public static class FacetDate extends JavaScriptObject {

			protected FacetDate() {
			}

			public final native String getName() /*-{
				return this["name"];
			}-*/;

			public final native JsArray<Hits> getHits() /*-{
				var hits = [];
				var i = -1;

				var value = this["value"];
				for (var prop in value){
					// improve the regex
					if (/^\d+-\d+-\d+T\d+:\d+:\d+Z$/.test(prop)){
						i++;
						hits[i] = {
							"name": prop,
							"value": value[prop]
						};
					}
				}

				return hits;
			}-*/;

			public final native String getEnd() /*-{
				return this["value"]["end"];
			}-*/;

			public final native String getGap() /*-{
				return this["value"]["gap"];
			}-*/;

			public final native int getAfter() /*-{
				return this["value"]["after"];
			}-*/;

			public final native int getBefore() /*-{
				return this["value"]["before"];
			}-*/;

			public final native int getBetween() /*-{
				return this["value"]["between"];
			}-*/;

		}
	}

	public static class ResponseHeader extends JavaScriptObject {

		protected ResponseHeader() {
		}

		public final native int getQTime() /*-{
			return this["QTime"];
		}-*/;

		public final native Params getParams() /*-{
			return this["params"];
		}-*/;

		public final native int getStatus() /*-{
			return this["status"];
		}-*/;

		public static class Params extends JavaScriptObject {

			protected Params() {
			}

			public final native String getQ() /*-{
				return this["q"];
			}-*/;

			public final native String getFq() /*-{
				return this["fq"];
			}-*/;

			public final native int getStart() /*-{
				var result = this["start"];
				if (!result){
					result = 0;
				}

				return parseInt(result);
			}-*/;

			public final native int getRows() /*-{
				var result = this["row"];
				if (!result){
					result = 10;
				}

				return parseInt(result);
			}-*/;

			public final native boolean getFacet() /*-{
				var result;

				if (this["facet"]) {
					result = true;
				} else {
					result = false;
				}

				return result;
			}-*/;

			public final native String getFacetDate() /*-{
				return this["facet.date"];
			}-*/;

			public final native String getFacetDateStart() /*-{
				return this["facet.date.start"];
			}-*/;

			public final native String getFacetDateEnd() /*-{
				return this["facet.date.end"];
			}-*/;

			public final native String getFacetDateGap() /*-{
				return this["facet.date.gap"];
			}-*/;

			public final native int getFacetMincount() /*-{
				return this["facet.mincount"];
			}-*/;

			public final native int getFacetLimit() /*-{
				return this["facet.limit"];
			}-*/;

			public final native JsArrayString getFacetField() /*-{
				return this["facet.field"];
			}-*/;
		}
	}

	public static class Response extends JavaScriptObject {

		protected Response() {
		}

		public final native int getStart() /*-{
			return this["start"];
		}-*/;

		public final native int getNumFound() /*-{
			return this["numFound"];
		}-*/;

		public final native JsArray<Doc> getDocs() /*-{
			return this["docs"];
		}-*/;

		/*
		 * TODO make array
		 */
		public static class Doc extends JavaScriptObject {

			protected Doc() {
			}

			public final native String getUri() /*-{
				return this["uri"];
			}-*/;

			public final native String getAppId() /*-{
				return this["app-id"];
			}-*/;

			public final native String getRequestPinyin() /*-{
				return this["request-pinyin"];
			}-*/;

			public final native JsArrayString getResponseDetailsChar() /*-{
				return this["response-details-char"];
			}-*/;

			// /**
			// * TODO
			// *
			// * @return
			// */
			// public final native Map<String, Integer>
			// getResponseDetailsConfidence() /*-{
			// return this["response-details-confidence-*"];
			// }-*/;
		}
	}

}
